#include "MultithreadTcpServer.h"

#include <boost/bind.hpp>
#include <tbb/tbb_thread.h>


using namespace boost::asio;
using namespace std;
using namespace tbb;


MultithreadTcpServer::MultithreadTcpServer(size_t threadPoolSize, unsigned short port /* = 80 */)
	: _acceptor(_ioService),
	  _newConnection(new ConcurrentTcpConnection(_ioService)),
	  _threadPoolSize(threadPoolSize)
{
	ip::tcp::endpoint endpoint(ip::tcp::v4(), port);

	_acceptor.open(endpoint.protocol());
	_acceptor.set_option(ip::tcp::acceptor::reuse_address(true));
	_acceptor.bind(endpoint);
	_acceptor.listen();

	StartAccept();
}

void MultithreadTcpServer::HandleAccept(const boost::system::error_code &error)
{
	if (!error)
	{
		_newConnection->Start();
		_newConnection.reset(new ConcurrentTcpConnection(_acceptor.io_service()));
		StartAccept();
	}
}

void MultithreadTcpServer::Run()
{
    while (true)
    {
	    vector<tbb_thread *> threads(_threadPoolSize - 1);

	    for (size_t i = 0; i < _threadPoolSize - 1; ++i)
	    {
		    threads[i] = new tbb_thread(boost::bind(&io_service::run, &_ioService));
	    }

	    _ioService.run();

	    for (size_t i = 0; i < _threadPoolSize - 1; ++i)
	    {
		    threads[i]->join();
		    delete threads[i];
	    }
    }
}

void MultithreadTcpServer::StartAccept()
{
	_acceptor.async_accept(_newConnection->getSocket(),
		boost::bind(&MultithreadTcpServer::HandleAccept, this, placeholders::error));
}